package com.cboy.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 自定义Realm
 * */
public class CustomRealm extends AuthorizingRealm {

    Map<String,String> userMap  = new HashMap<String,String>();
    {
        //userMap.put("andy","123456");//加密前使用
        //userMap.put("andy","e10adc3949ba59abbe56e057f20f883e");//加密后使用
        userMap.put("andy","7f2da63a63b9ba3406d60c6903b1096e");//加盐加密后使用
        super.setName("安迪");
    }
    //自定义授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String)principalCollection.getPrimaryPrincipal();
        Set<String> roles  = getRolesByUsername(username);
        Set<String> permissions  = getPermissionsByUsername(username);
        SimpleAuthorizationInfo simpleAuthorizationInfo  = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setRoles(roles);
        simpleAuthorizationInfo.setStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    private Set<String> getPermissionsByUsername(String username) {
        Set<String> permissions = new HashSet<String>();
        permissions.add("user:delete");
        return permissions;
    }

    //模拟从数据库或缓存中获取用户角色
    private Set<String> getRolesByUsername(String username) {
        Set<String> roles = new HashSet<String>();
        roles.add("admin");
        return roles;
    }

    //自定义认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        //1.从主体传过来的信息中获取用户名
        String username = (String)authenticationToken.getPrincipal();
        //2.通过用户名从数据库中获取凭证
        String password = getPasswordByUsername(username);
        if(password==null){
            return null;
        }
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("andy",password,"安迪");
        //设置盐值
        authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("andy"));//加盐

        return authenticationInfo;
    }

    //模拟读取数据库
    private String getPasswordByUsername(String username) {
        return userMap.get(username);
    }

    //计算加密后的值
    public static void main(String[] args) {
        //Md5Hash md5 = new Md5Hash("123456");加密
        Md5Hash md5 = new Md5Hash("123456","andy");//加盐
        System.out.println(md5.toString());
    }
}
